/**
 * WidgetAnimation module
 */

var React = require("react");
import { connect } from 'dva';
import classnames from 'classnames';
import { bindActionCreators } from 'redux';
import editorActions from "../../../actions/Editor/editor";
import timelineActions from "../../../actions/Editor/timelines";
import widgetsActions from "../../../actions/Editor/widgets";
import tool from "../../../utils/tool";

var consts = require("../../../utils/consts");
var storage = require("../../../utils/storage");
var AnimationForm = require("./AnimationForm");
var pathProvider = require("../../provider/pathProvider");
var dataProvider = require("../../provider/dataProvider");
//var BasePermission = require("../model/BasePermission");
var alertProvider = require("../../provider/alertProvider");
var WidgetAnimation = React.createClass({
    getInitialState: function (){
        return {
            form: {
                model: null
            },
            listView: true,
            showAnimation: false
        }
    },
    getInitialProps: function (){
        return {
            root: {},
            widget: {},
            timelines: {},
            selectedTimeline: {}
        }
    },
    componentWillMount: function (){
        var widget = this.props.widget, type = widget.type;
        var animationTypeStructs = consts.ANIMATION_TYPE_STRUCTS;

        this.timelines = [];
        this.sourceAnTypes = animationTypeStructs || [];
        this.permissionFactory = {};
//        BasePermission.get(function (result){
//            this.permissionFactory = result;
//            if (this.permissionFactory.animationTypes){
//                for (var i=0; i<animationTypeStructs.length; i++){
//                    if (this.permissionFactory.animationTypes & (1 << i)){
//                        var animation_type = animationTypeStructs[i].an_type;
//                        // 3d模型仅支持部分动效
//                        if (type == consts.WIDGET_TYPE.THREED){
//                            if ($.inArray(animation_type, consts.WIDGET_IN_THREED_ANIMATION_TYPE) != -1){
//                                this.sourceAnTypes.push($.extend(true, {}, animationTypeStructs[i]));
//                            }
//                        } else if(type == consts.WIDGET_TYPE.VIDEO){
//                            if ($.inArray(animation_type, consts.WIDGET_IN_VIDEO_ANIMATION_TYPE) != -1){
//                                this.sourceAnTypes.push($.extend(true, {}, animationTypeStructs[i]));
//                            }
//
//                        } else {
//                             this.sourceAnTypes.push($.extend(true, {}, animationTypeStructs[i]));
//                        }
//                    }
//                }
//            }
//        }.bind(this), function (){
//
//        });
    },
    updateTimeline: function (timeline){
        dataProvider.updateSelectedTimeline(storage.data.selectedWidgetId, timeline);
    },
    toggleListView: function (){
        const {editMode} = this.props;
        this.setState({
            listView: false
        });
        if(editMode == consts.EDIT_MODE.PATH) this.handleOnQuitEditPath();
    },
    handleOnToggleAnimationlist: function (){
        this.setState({
            showAnimation: !this.state.showAnimation
        });
    },
    handleOnCheckAntype: function (e){
        this.toggleListView();

        var root = this.props.root;
        const {timelines,widget:focusWidget,editMode:currentEditMode,setState} = this.props;
        var sourceAnTypes = this.sourceAnTypes;
        var className = "animation-type-source";

        var element = $(e.target || e.srcElement);
        element = element.hasClass(className) ? element : element.parents("." + className);

        var type = element.attr("data-type");

        this.form = {
            name: 'TimelineForm'
        };
        //初始化动画开始时间和结束时间
        var length = timelines.length,start_time = 0,end_time = 1;
        if(length){
            start_time = parseFloat(timelines[length-1].end_time);
            end_time = start_time + end_time;
        }
        if(end_time > 60){
            //上一个动效的end_time = 60 ,怎么处理新增动效
        }
        this.timeline = {
            end_time: end_time,
            if_music: 0,
            start_time: start_time,
            unsaved: true,
            an_types: [],
            tween: 1
        };
        storage.data.selectedTimeline = this.timeline;

        var an_type = this.getAnTypeByType(type);
        // 截获路径动画Path选择
        if ($.inArray(an_type.an_type, consts.WIDGET_HAS_PATH_ANIMATION_TYPE) != -1){
            var points = [{
                x: 0,
                y: 0
            }];
            // 自动计算出一个点，并且始终保持在可视区域
            var np = this.countNextPointByFocusWidget(focusWidget);
            np = {
                x: np.x - focusWidget.offset_x,
                y: np.y - focusWidget.offset_y
            }
            points.push(np);
            
            this.onEditModeChange(consts.EDIT_MODE.PATH, points, focusWidget);
            
            an_type.points = an_type.points ? an_type.points : points;//有路径的动效初始points为空的情况
            this.addAnType(an_type);
        } else {
            //updateEditMode();
            this.addAnType(an_type);
        }
        this.handleOnToggleAnimationlist();
    },
    onEditModeChange (editMode = consts.EDIT_MODE.PAGE, points = [], widget = {}) {
         const {setState} = this.props;
         setState({editMode: editMode});
          if (editMode != consts.EDIT_MODE.PATH){
              // 切回到编辑模式
//              storage.data.disableCanvasSelectable = false;
              pathProvider.clearPoints();
          } else {
              // 切换到PATH模式
//              storage.data.disableCanvasSelectable = true;
              // clear points
              const {updateWidget,updateTimeline,selectedTimeline} = this.props;

              pathProvider.setWidgetId(widget.widget_id);
              pathProvider.setWidget(widget);
              pathProvider.setState(setState);
              pathProvider.updateWidget(updateWidget);
              pathProvider.updateTimeline(updateTimeline);
              pathProvider.setTimeline(selectedTimeline);
              pathProvider.clearPoints();
              points.forEach((point) => {
                  pathProvider.addPoint(point.x, point.y);
              });
          }
      },
    // 初始化动效， 交互后台，创建
    addAnType: function (an_type){
        an_type = this.initAnType(an_type);

        // $scope.nav.openAnType
        storage.data.selectedAnType = an_type;
        // $scope.nav.openAnTypeId
        storage.data.selectedAnTypeId = an_type.an_type;
        // 添加动效时压入初始化以后的数据
        // $scope.nav.focusTimeline.an_types
        storage.data.selectedTimeline.an_types.push(an_type);
        this.createAnimation(storage.data.selectedTimeline);
        pathProvider.setTimeline(storage.data.selectedTimeline);
    },
    // 更新路径点
    updatePathPoint: function (){
       var an_types = this.sourceAnTypes;
       for (var i = 0; i < an_types.length; i++){
           var an_type = an_types[i];
           if ($.inArray(an_type.an_type, consts.WIDGET_HAS_PATH_ANIMATION_TYPE) != -1){
               if (pathProvider.changed){
                   an_type.points = pathProvider.getPoints();
                   pathProvider.changed = false;
               }
           }
       };
    },
    // 交互后台，创建timeline
    createAnimation: function (timeline){
        var data = storage.data;
        var root = this.props.root;
        var widget = this.props.widget;
        // 如果动画中路径动画，则更新相应点
        // 更新editmode
        this.updatePathPoint();
        const {addTimeLine,selectedWidgetId,selectedPageId} = this.props;
        timeline.widget_id = selectedWidgetId;
        timeline.page_id = selectedPageId;
        addTimeLine({timeline: timeline, widget_id: selectedWidgetId})

//        function successNewFn (timeline){
//            dataProvider.queryTimelinesByWidgetId(widget.id, function (){
//                root.updateSelectedTimeline(timeline);
//                root.updateTimelines(dataProvider.timelines);
//
//                data.selectedTimeline = timeline;
//                data.selectedTimelineId = timeline.id;
//                data.selectedWidgetTimelineId = timeline.id;
//                root.updateSelectedTimeline(timeline);
//
//            });
//        }
//        function errorFn (json){
//            alertProvider.error(json.data && json.data.message || 'Your button could not be saved. Please try again later.');
//            data.selectedTimelineId = this.timeline.id;
//        }
//        dataProvider.saveTimelineAnimation(data.selectedWidgetId, data.selectedTimeline, successNewFn, errorFn, root);
    },
    // 初始化动效参数。因为现在是添加就和服务器交互。原来通过form表单提交，可由angular ng-init在生成DOM树的时候初始化
    initAnType: function (an_type){
        var AN_TYPE = consts.AN_TYPE;
        switch (an_type.an_type){
            case AN_TYPE.ERASE:
            case AN_TYPE.FLY_INTO:
            case AN_TYPE.CUT:
            case AN_TYPE.BOUNCE:
            case AN_TYPE.ROTATE_FLY_INTO:
            case AN_TYPE.LIGHT_ERASE:
                an_type.direction = 0;
                break;
            case AN_TYPE.FLICKER:
            case AN_TYPE.ZOOM:
                an_type.loop_type = 0;
                an_type.start_value = 0;
                an_type.end_value = 1;
                break;
            case AN_TYPE.ROTATE:
                an_type.loop_type = 0;
                an_type.start_value = 0;
                an_type.end_value = 360;
                break;
            case AN_TYPE.TRUN:
                an_type.loop_type = 0;
                an_type.start_rotate_x = 0;
                an_type.start_rotate_y = 0;
                an_type.end_rotate_x = 0;
                an_type.end_rotate_y = 0;
                break;
            case AN_TYPE.PATH:
            case AN_TYPE.ZOOM_MOVE:
            case AN_TYPE.FADE_IN_MOVE:
                an_type.auto_rotate = false;
                an_type.loop_type = 0;
                break;
            case AN_TYPE.ZOOMOUT:
                an_type.start_value = 1;
                an_type.end_value = 0;
        }
        return an_type;
    },
    countNextPointByFocusWidget: function (focusWidget){
        var fp = {
                x: focusWidget.offset_x,
                y: focusWidget.offset_y,
                width: focusWidget.width,
                height: focusWidget.height
            },
            np = {},
            right, top;
        if (fp.x > 0){
            right = true;
        }
        if (fp.y > 0){
            top = true;
        }
        if (right) np.x = fp.x - fp.width - 100;
        else np.x = fp.x + fp.width + 100;
        if (top) np.y = fp.y - fp.height - 100;
        else np.y = fp.y + fp.height + 100;

        return np;
    },
    getAnTypeByType: function (type){
        var result = this.sourceAnTypes.filter(function (an_type){
            return an_type.an_type == type;
        });

        if (result.length) return result[0];
        return null;
    },
    getTimelineById: function (id){
        const {timelines} = this.props;
        var result = timelines.filter(function (timeline){
            return id == timeline.id;
        });

        if (result.length) return result[0];
        return null;
    },
    handleOnTimelineClick: function (e){
        this.toggleListView();

        var root = this.props.root;
        var className = "btg-widget-animation";
        var element = $(e.target || e.srcElement);
        element = element.hasClass(className) ? element : element.parents("." + className);

        var timeline_id = element.attr("data-id");
        var timeline = this.getTimelineById(timeline_id);

        this.setState({
            form: {
                model: timeline
            }
        });

        const {setState} = this.props;
        setState({selectedTimeline: timeline,selectedTimelineId: timeline.id});
    },
    checkListView: function (){
        var selectedTimeline = this.props.selectedTimeline || {};
        const {timelines} = this.props;
        var result = timelines.filter(function (timeline){
            return timeline.id == selectedTimeline.id;
        });
        return !result.length;
    },
    handleOnQuitEditPath: function (){
        this.onEditModeChange(consts.EDIT_MODE.PAGE);
    },
    handleOnToggleShowTimeline (){
        //AnimationForm中调用
        const {setState,showTimeline}=this.props;
        setState({
            showlist: true,
            showTimeline: !showTimeline
        });
    },
    render: function (){
        const {widget,timelines,status,selectedTimeline: currentTimeline,removeTimeline,setState,updateTimeline,updateTimelines,widgets,editMode} = this.props;
        let sourceAnTypes = this.sourceAnTypes;

        let selectedTimeline = currentTimeline || {};

        let listView = this.checkListView();
        listView = listView ? this.state.listView : listView;

        if (!listView) this.state.form.model = selectedTimeline;
        var listViewNode = "";
        if (!listView){
            var animationFormNode = "";
            if (this.state.form.model){
                animationFormNode = <AnimationForm widget={widget} form={this.state.form} selectedTimeline={selectedTimeline}
                                   removeTimeline={removeTimeline} status={status}
                                   parent={this} timelines={timelines}
                                   handleOnToggleShowTimeline={()=>this.handleOnToggleShowTimeline()}
                                   updateTimeline={updateTimeline} updateTimelines={updateTimelines}
                                   setState={setState} parent={this} editMode={editMode} />

            }

            listViewNode =
                <div data-animation-form data-list-view="listView">
                    {animationFormNode}
                </div>
        }
        this.color = widget.action.triggered_color;
        return (
            <div className="animation-container">
                <div className="addWidgetAni">
                    <button onClick={this.handleOnToggleAnimationlist} type="button" className="addsucai" disabled={timelines.length >= consts.ANIMATION_MAX_NUM}><span className='button-item'>{timelines.length < consts.ANIMATION_MAX_NUM ? $._('Add animation') : $._('Reached the animation limit')}</span></button>
                    <div className="animation-container-list animationlist">
                    {
                        timelines.map(function (timeline){
                            if (timeline.id == selectedTimeline.id){
                                timeline = selectedTimeline;
                            }
                            timeline.end_time = parseFloat(timeline.end_time).toFixed(1);
                            let triggeredColor = tool.getTriggerColorByTimeline(widgets,timeline)|| timeline.trigger_color;
                            return (
                                <figure key={timeline.id} data-id={timeline.id} onClick={this.handleOnTimelineClick} id={"widget-animation-id-" + timeline.id} className={"btg-widget-animation " + (selectedTimeline.id === timeline.id ? "focus" : "")}>
                                    <div className="anilit" style={{borderColor: (selectedTimeline.id === timeline.id ? triggeredColor : "")}}>
                                        <div className="icon-group" style={{background: triggeredColor}}></div>
                                        <span className="time-label">
                                            {timeline.start_time + "-" + timeline.end_time}
                                        </span>
                                        <span className="title-label">
                                            {timeline.an_types[0].an_type_display}
                                        </span>
                                    </div>
                                </figure>
                            )
                        }.bind(this))
                    }
                    </div>
                </div>
                <div className="animation-types-source animation-group group-animation" style={{display: this.state.showAnimation ? "block" : "none"}}>
                    <div className='animation_hidden_title'>
                        <div>{$._('appear animation')}</div>
                    </div>
                    <div className='animations-appear'>
                        {
                            sourceAnTypes.map(function (an_type){
                                if(consts.WIDGET_FADE_IN_ANIMATION_TYPE.indexOf(an_type.an_type)>-1){
                                     return (
                                        <div key={an_type.an_type} data-type={an_type.an_type} onClick={this.handleOnCheckAntype} className="animation-type-source animation-type anima-hidden">
                                            <span>{an_type.an_type_display}</span>
                                        </div>
                                    )
                                }
                            }.bind(this))
                        }
                    </div>
                    <div className='animation_hidden_title'>
                        <div>{$._('disappear animation')}</div>
                    </div>
                    <div className='animations-disappear'>
                        {
                            sourceAnTypes.map(function (an_type){
                                if(consts.WIDGET_FADE_OUT_ANIMATION_TYPE.indexOf(an_type.an_type)>-1){
                                     return (
                                        <div key={an_type.an_type} data-type={an_type.an_type} onClick={this.handleOnCheckAntype} className="animation-type-source animation-type anima-hidden">
                                            <span>{an_type.an_type_display}</span>
                                        </div>
                                    )
                                }
                            }.bind(this))
                        }
                    </div>
                </div>
                {listViewNode}
            </div>
        )
    }
});

const mapStateToProps = ({editor, widgets, timelines, pages, pageJump, pageTimelines}) => {
    const pageId = editor.selectedPageId;
    const widgetId = editor.selectedWidgetId;
    return {
        selectedPageId: editor.selectedPageId,
        focusTab: editor.focusTab,
        fromTemplate: editor.fromTemplate,
        selectedWidgetIds: editor.selectedWidgetIds,
        selectedWidgetId: editor.selectedWidgetId,
        selectedWidget: editor.selectedWidget,
        selectedTimeline: editor.selectedTimeline,
        selectedTimelineId: editor.selectedTimelineId,
        widgets: widgets.filter(w => w.page_id === pageId),
        timelines: timelines.filter(t => t.widget_id == widgetId).filter(t => t.delFlag !== true),
        page: pages.filter(p => p.page_id === pageId)[0],
        widget: editor.selectedWidget,
        status: editor.status,
        editMode: editor.editMode,
        showTimeline: editor.showTimeline,
    };
};

const mapDispatchToProps = (dispatch) => {
    return bindActionCreators({...editorActions,...timelineActions,...widgetsActions}, dispatch);
};


export default connect(mapStateToProps, mapDispatchToProps)(WidgetAnimation);

